﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ProjectNocturnalFool
{
    public enum VelocityType
    {
        acceleration,
        lowPass,
        vector2lowPass
    }

    public enum SpeedDirection
    {
        Up,
        Down
    }

    public class Velocity
    {        
        public float targetSpeed {get; set;}
        public float acceleration {get; set;}
        public float lowPassFactor { get; set; }
        public float currentSpeed { get; set; }

        public Vector2 targetVelocity { get; set; }
        public Vector2 accelerationVector { get; set; }
        public Vector2 currentVelocity { get; set; }

        VelocityType type;
        SpeedDirection direction;
 
        /// <summary>
        /// Constructor for an accelerating/deccelerating object
        /// </summary>
        /// <param name="sSpeed">Starting Speed</param>
        /// <param name="tSpeed">Target Speed to stop accelerating at</param>
        /// <param name="acc">Acceleration Speed</param>
        /// <param name="speedDirection">Whether to deccelerate or accelerate</param>
        public Velocity(float sSpeed, float tSpeed, float acc, SpeedDirection speedDirection)
        {
            currentSpeed = sSpeed;
            targetSpeed = tSpeed;
            acceleration = acc;
            type = VelocityType.acceleration;
            direction = speedDirection;
        }

        /// <summary>
        /// Constructor for a lowpassing object
        /// </summary>
        /// <param name="sSpeed">Starting Speed</param>
        /// <param name="tSpeed">Target Speed</param>
        /// <param name="lowPassFact">Factor from 0-1 that affects how fast target speed is reached (1 is higher)</param>
        public Velocity(float sSpeed, float tSpeed, float lowPassFact)
        {
            currentSpeed = sSpeed;
            targetSpeed = tSpeed;
            type = VelocityType.lowPass;
            lowPassFactor = lowPassFact;
        }

        public Velocity(Vector2 sVel, Vector2 tVel, float lowPassFact) {
            currentVelocity = sVel;
            targetVelocity = tVel;
            type = VelocityType.vector2lowPass;
            lowPassFactor = lowPassFact;
        }

        /// <summary>
        /// Updates the values for either acceleration or lowpass objects
        /// </summary>
        public void Update()
        {
            if(type == VelocityType.acceleration)
            {
                UpdateAcceleration();
            }
            else if (type == VelocityType.lowPass)
            {
                UpdateLowPass();
            }
            else if (type == VelocityType.vector2lowPass) {
                UpdateVector2LowPass();
            }
        }

        /// <summary>
        /// Updates current speed by simply adding the acceleration value
        /// </summary>
        private void UpdateAcceleration()
        {
            int dir = direction == SpeedDirection.Up ? 1 : -1;
            if (currentSpeed * dir < targetSpeed * dir)
            {
                currentSpeed += acceleration * dir;
            }
        }

        /// <summary>
        /// Low passes the value up to the target
        /// </summary>
        private void UpdateLowPass()
        {
            currentSpeed = currentSpeed + lowPassFactor * (targetSpeed - currentSpeed);
        }

        private void UpdateVector2LowPass()
        {
            currentVelocity = currentVelocity + lowPassFactor * (targetVelocity - currentVelocity);
        }

    }
}
